package com.sanyou.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sanyou.enums.IsOk;
import com.sanyou.mapper.EquipmentMapper;
import com.sanyou.mapper.FactoryMapper;
import com.sanyou.mapper.IndustryDataMapper;
import com.sanyou.pojo.*;
import com.sanyou.pojo.vo.*;
import com.sanyou.service.*;
import com.sanyou.utils.PagedResult;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * User: asus
 * Date: 2021/6/14
 * Time: 15:02
 * Version:V1.0
 */
@Service
public class IndustryDataServiceImpl implements IndustryDataService {

    @Resource
    private IndustryDataMapper industryDataMapper;

    @Resource
    private EquipmentMapper equipmentMapper;
    
    @Resource
    private EquipmentService equipmentService;

    @Resource
    private FactoryService factoryService;

    @Resource
    private CopperParticleService copperParticleService;

    @Resource
    private UserService userService;

    @Resource
    private FactoryMapper factoryMapper;

    @Resource
    private DataInfoService dataInfoService;

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<IndustryDataVo> getPieChart(IndustryDataVo industryDataVo) {

        Example example = new Example(Equipment.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("equipNo",industryDataVo.getLineno());
        List<Equipment> equipmentList = equipmentMapper.selectByExample(example);

        if(equipmentList != null && equipmentList.size()>0){
            industryDataVo.setEquipHealthLimit(equipmentList.get(0).getEquipHealthLimit());
            industryDataVo.setEquipSubhealthLimit(equipmentList.get(0).getEquipSubhealthLimit());
            List<IndustryDataVo> result = industryDataMapper.getPieChart(industryDataVo);
            return result;
        }else {
            return new ArrayList<>();
        }
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<IndustryDataVo> getBarChart(IndustryDataVo industryDataVo) {

        Example example = new Example(Equipment.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("equipNo",industryDataVo.getLineno());
        List<Equipment> equipmentList = equipmentMapper.selectByExample(example);

        List<IndustryDataVo> result = new ArrayList<>();
        if(equipmentList != null && equipmentList.size()>0){
            industryDataVo.setEquipHealthLimit(equipmentList.get(0).getEquipHealthLimit());
            industryDataVo.setEquipSubhealthLimit(equipmentList.get(0).getEquipSubhealthLimit());

            Date startTime = industryDataVo.getStartTime();
            Date endTime = industryDataVo.getEndTime();
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            while(DateUtils.truncatedCompareTo(startTime,endTime, Calendar.DATE)<0){
                industryDataVo.setStartTime(startTime);

                Calendar calendar = new GregorianCalendar();
                calendar.setTime(startTime);
                calendar.add(Calendar.DATE,1);
                startTime = calendar.getTime();
                industryDataVo.setEndTime(startTime);
                List<IndustryDataVo> getList = industryDataMapper.getPieChart(industryDataVo);

                IndustryDataVo vo = new IndustryDataVo();

                String dateStr = format.format(industryDataVo.getStartTime());
                vo.setDate(dateStr);
                for (IndustryDataVo dataVo : getList) {
                    if("健康".equals(dataVo.getName())){
                        vo.setHealthValue(dataVo.getValue());
                    }else if("亚健康".equals(dataVo.getName())){
                        vo.setSubHealthValue(dataVo.getValue());
                    }else if("不健康".equals(dataVo.getName())){
                        vo.setUnHealthValue(dataVo.getValue());
                    }
                }
                result.add(vo);
            }
        }
        return result;
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<IndustryDataVo> getLineChart(IndustryDataVo industryDataVo) {
        Example example = new Example(Equipment.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("equipNo",industryDataVo.getLineno());
        List<Equipment> equipmentList = equipmentMapper.selectByExample(example);

        List<IndustryDataVo> result = new ArrayList<>();
        if(equipmentList != null && equipmentList.size()>0){
            industryDataVo.setEquipHealthLimit(equipmentList.get(0).getEquipHealthLimit());
            industryDataVo.setEquipSubhealthLimit(equipmentList.get(0).getEquipSubhealthLimit());

            Date startTime = industryDataVo.getStartTime();
            Date endTime = industryDataVo.getEndTime();
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            while(DateUtils.truncatedCompareTo(startTime,endTime, Calendar.DATE)<0){
                industryDataVo.setStartTime(startTime);

                Calendar calendar = new GregorianCalendar();
                calendar.setTime(startTime);
                calendar.add(Calendar.DATE,1);
                startTime = calendar.getTime();
                industryDataVo.setEndTime(startTime);
                List<IndustryDataVo> getList = industryDataMapper.getPieChart(industryDataVo);

                IndustryDataVo vo = new IndustryDataVo();

                String dateStr = format.format(industryDataVo.getStartTime());
                vo.setDate(dateStr);
                for (IndustryDataVo dataVo : getList) {
                    if("健康".equals(dataVo.getName())){
                        vo.setHealthValue(dataVo.getValue());
                    }else if("亚健康".equals(dataVo.getName())){
                        vo.setSubHealthValue(dataVo.getValue());
                    }else if("不健康".equals(dataVo.getName())){
                        vo.setUnHealthValue(dataVo.getValue());
                    }
                }
                result.add(vo);
            }
        }
        return result;
    }


    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public PagedResult query(IndustryDataVo industryDataVo,Integer page, Integer pageSize) {

        //数据字典查询name(前端叫name，其实是data_code)类型
        List<DataInfoDetail> healthTypeList = dataInfoService.getDataInfoDetailsById("3","1");
        for (DataInfoDetail dataInfoDetail : healthTypeList) {
            if (dataInfoDetail.getDataCode().equals(industryDataVo.getName())){
                if(dataInfoDetail.getDataCode().equals("0")){
                    industryDataVo.setName("");
                }else {
                    industryDataVo.setName(dataInfoDetail.getDataName());
                }

            }
        }


        Example example = new Example(Equipment.class);
        Example.Criteria criteria = example.createCriteria();

        criteria.andEqualTo("equipNo",industryDataVo.getLineno());

        List<Equipment> equipmentList = equipmentMapper.selectByExample(example);

        List<IndustryDataVo> result = new ArrayList<>();
        if(equipmentList != null && equipmentList.size()>0){
            industryDataVo.setEquipHealthLimit(equipmentList.get(0).getEquipHealthLimit());
            industryDataVo.setEquipSubhealthLimit(equipmentList.get(0).getEquipSubhealthLimit());

            PageHelper.startPage(page,pageSize);

            List<IndustryDataVo> list = industryDataMapper.query(industryDataVo);
            PageInfo<IndustryDataVo> pageList = new PageInfo<>(list);

            PagedResult pagedResult = new PagedResult();
            pagedResult.setPage(page);
            pagedResult.setTotal(pageList.getPages());
            pagedResult.setRows(list);
            pagedResult.setRecords(pageList.getTotal());
            return pagedResult;

        }
        return (PagedResult) result;
    }


    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<IndustryDataVo> getCycleLineChart(IndustryDataVo industryDataVo) {
        Example example = new Example(Equipment.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("equipNo",industryDataVo.getLineno());
        List<Equipment> equipmentList = equipmentMapper.selectByExample(example);

        if(equipmentList != null && equipmentList.size()>0){
            int equipCycle = equipmentList.get(0).getEquipCycle();
            Date startTime = industryDataVo.getStartTime();
            Date endTime = industryDataVo.getEndTime();

            industryDataVo.setEquipHealthLimit(equipmentList.get(0).getEquipHealthLimit());
            industryDataVo.setEquipSubhealthLimit(equipmentList.get(0).getEquipSubhealthLimit());
            //计算endTime到startTime之间的实际天数。同一天视为1。
            long day = Math.abs(endTime.getTime() - startTime.getTime())/(1000 * 60 * 60 * 24) + 1;
            int cycleCount = 0;
            //计算endTime到startTime之间一共有几个周期。不足1周期加1
            if(day % equipCycle == 0)
                cycleCount = (int) (day/equipCycle);
            else
                cycleCount = (int) (day/equipCycle) + 1;
            //为每一个周期的vo塞入endTime和startTime
            List<IndustryDataVo> result = new ArrayList<>();
            SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
            for(int i =0;i<cycleCount;i++){
                industryDataVo.setStartTime(startTime);
                Calendar calendar = new GregorianCalendar();
                calendar.setTime(startTime);
                calendar.add(Calendar.DATE,equipCycle);
                startTime = calendar.getTime();
                industryDataVo.setEndTime(startTime);
                //最后一个周期直接插入endTime值。
                if(i == cycleCount-1)
                    industryDataVo.setEndTime(endTime);
                //查询一个周期的数据
                List<IndustryDataVo> getList = industryDataMapper.getPieChart(industryDataVo);

                IndustryDataVo vo = new IndustryDataVo();
                String startStr = format.format(industryDataVo.getStartTime());
                //由于数据库查询的时候,日期设置为每天的0点到0点,导致查询数据的时间和前端展示的时间不同
                calendar.setTime(industryDataVo.getEndTime());
                calendar.add(Calendar.DATE,-1);
                String endStr = format.format(calendar.getTime());
                vo.setDate(startStr + "-" + endStr);

                for (IndustryDataVo dataVo : getList) {
                    if("健康".equals(dataVo.getName())){
                        vo.setHealthValue(dataVo.getValue());
                    }else if("亚健康".equals(dataVo.getName())){
                        vo.setSubHealthValue(dataVo.getValue());
                    }else if("不健康".equals(dataVo.getName())){
                        vo.setUnHealthValue(dataVo.getValue());
                    }
                }
                result.add(vo);
            }
            return result;
        }
        return new ArrayList<>();
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<IndustryDataVo> getNormalLineChart(IndustryDataVo industryDataVo) {
        Example example = new Example(Equipment.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("equipNo",industryDataVo.getLineno());
        List<Equipment> equipmentList = equipmentMapper.selectByExample(example);

        if(equipmentList != null && equipmentList.size()>0){
            int equipCycle = equipmentList.get(0).getEquipCycle();
            int tag = 3;
            boolean flag = true;
            if(equipCycle > tag) {
                do {
                    if (equipCycle % tag == 0) {
                        equipCycle /= tag;
                        flag = false;
                    } else
                        tag++;
                } while (flag);
            }

            Date startTime = industryDataVo.getStartTime();
            Date endTime = industryDataVo.getEndTime();

            industryDataVo.setEquipHealthLimit(equipmentList.get(0).getEquipHealthLimit());
            industryDataVo.setEquipSubhealthLimit(equipmentList.get(0).getEquipSubhealthLimit());

            long day = Math.abs(endTime.getTime() - startTime.getTime())/(1000 * 60 * 60 * 24) + 1;
            int cycleCount = 0;
            if(day % equipCycle == 0)
                cycleCount = (int) (day/equipCycle);
            else
                cycleCount = (int) (day/equipCycle) + 1;

            List<IndustryDataVo> result = new ArrayList<>();
            SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
            for(int i =0;i<cycleCount;i++){
                industryDataVo.setStartTime(startTime);
                Calendar calendar = new GregorianCalendar();
                calendar.setTime(startTime);
                calendar.add(Calendar.DATE,equipCycle);
                startTime = calendar.getTime();
                industryDataVo.setEndTime(startTime);
                if(i == cycleCount-1)
                    industryDataVo.setEndTime(endTime);

                List<IndustryDataVo> getList = industryDataMapper.getPieChart(industryDataVo);

                IndustryDataVo vo = new IndustryDataVo();
                String startStr = format.format(industryDataVo.getStartTime());
                //由于数据库查询的时候,日期设置为每天的0点到0点,导致查询数据的时间和前端展示的时间不同
                calendar.setTime(industryDataVo.getEndTime());
                calendar.add(Calendar.DATE,-1);
                String endStr = format.format(calendar.getTime());
                vo.setDate(startStr + "-" + endStr);

                for (IndustryDataVo dataVo : getList) {
                    if("健康".equals(dataVo.getName())){
                        vo.setHealthValue(dataVo.getValue());
                    }else if("亚健康".equals(dataVo.getName())){
                        vo.setSubHealthValue(dataVo.getValue());
                    }else if("不健康".equals(dataVo.getName())){
                        vo.setUnHealthValue(dataVo.getValue());
                    }
                }
                result.add(vo);
            }
            return result;
        }
        return new ArrayList<>();
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<IndustryDataVo> getNormalLineChart2(IndustryDataVo industryDataVo) {

        double max = industryDataMapper.getMax(industryDataVo);

        //分组
        int step = 0;
        List<Integer> levelNums = new ArrayList<>();
        List<String> levelNames = new ArrayList<>();
        levelNums.add(step);
        step+=5;
        while(step<max){
            levelNames.add((step-5) + "-" + (step));
            levelNums.add(step);
            step+=5;
        }
        levelNames.add((step-5) + "-" + (step));

        industryDataVo.setLevelNums(levelNums);
        industryDataVo.setLevelNames(levelNames);

        if(max == 0){
            return new ArrayList<>();
        }else{
            List<IndustryDataVo> getList = industryDataMapper.getNormalLineChart(industryDataVo);
            List<IndustryDataVo> result = new ArrayList<>();
            int id = 1;
            for (String levelName : levelNames) {
                IndustryDataVo vo = new IndustryDataVo();
                vo.setId(id++);
                vo.setName(levelName);
                IndustryDataVo vo1 = getList.stream().filter(t -> levelName.equals(t.getName())).findFirst().orElse(null);
                if(vo1 != null)
                    vo.setValue(vo1.getValue());
                else
                    vo.setValue(0);

                result.add(vo);
            }
            return result;
        }
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<IndustryDataVo> getNormalBarChart(IndustryDataVo industryDataVo) {
        Example example = new Example(Equipment.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("equipNo",industryDataVo.getLineno());
        List<Equipment> equipmentList = equipmentMapper.selectByExample(example);

        List<IndustryDataVo> result = new ArrayList<>();
        if(equipmentList != null && equipmentList.size()>0){
            industryDataVo.setEquipHealthLimit(equipmentList.get(0).getEquipHealthLimit());
            industryDataVo.setEquipSubhealthLimit(equipmentList.get(0).getEquipSubhealthLimit());

            Date startTime = industryDataVo.getStartTime();
            Date endTime = industryDataVo.getEndTime();
            SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");

            int equipCycle = equipmentList.get(0).getEquipCycle();
            int tag = 3;
            boolean flag = true;
            if(equipCycle > tag) {
                do {
                    if (equipCycle % tag == 0) {
                        equipCycle /= tag;
                        flag = false;
                    } else
                        tag++;
                } while (flag);
            }
            long day = Math.abs(endTime.getTime() - startTime.getTime())/(1000 * 60 * 60 * 24) + 1;
            int cycleCount = 0;
            if(day % equipCycle == 0)
                cycleCount = (int) (day/equipCycle);
            else
                cycleCount = (int) (day/equipCycle) + 1;

            for(int i =0;i<cycleCount;i++){
                industryDataVo.setStartTime(startTime);
                Calendar calendar = new GregorianCalendar();
                calendar.setTime(startTime);
                calendar.add(Calendar.DATE,equipCycle);
                startTime = calendar.getTime();
                industryDataVo.setEndTime(startTime);
                if(i == cycleCount-1)
                    industryDataVo.setEndTime(endTime);

                List<IndustryDataVo> getList = industryDataMapper.getPieChart(industryDataVo);
                IndustryDataVo vo = new IndustryDataVo();
                String startStr = format.format(industryDataVo.getStartTime());
                //由于数据库查询的时候,日期设置为每天的0点到0点,导致查询数据的时间和前端展示的时间不同
                calendar.setTime(industryDataVo.getEndTime());
                calendar.add(Calendar.DATE,-1);
                String endStr = format.format(calendar.getTime());
                vo.setDate(startStr + "-" + endStr);
                for (IndustryDataVo dataVo : getList) {
                    if("健康".equals(dataVo.getName())){
                        vo.setHealthValue(dataVo.getValue());
                    }else if("亚健康".equals(dataVo.getName())){
                        vo.setSubHealthValue(dataVo.getValue());
                    }else if("不健康".equals(dataVo.getName())){
                        vo.setUnHealthValue(dataVo.getValue());
                    }
                }
                result.add(vo);
            }
        }
        return result;
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public IndustryDataVo queryData(IndustryDataVo industryDataVo, Integer page){
        PageHelper.startPage(page,1);

        List<IndustryData> list = industryDataMapper.queryData(industryDataVo);
        int count = industryDataMapper.countData(industryDataVo);

        IndustryDataVo vo = new IndustryDataVo();
        if(list != null && list.size() > 0){
            IndustryData industryData = list.get(0);
            BeanUtils.copyProperties(industryData,vo);
            vo.setPage(page);
            vo.setTotal(count);
            vo.setRecords(count*26);

            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String date = format.format(industryData.getDatatime());
            vo.setDate(date);

            List<TableData> tableDataList = new ArrayList<>();
            for(int i=1;i<=26;i++){
                try {
                    Field field = industryData.getClass().getDeclaredField("max" + i);
                    field.setAccessible(true);
                    String values = (String) field.get(industryData);
                    String[] split = values.split(",");

                    TableData tableData = new TableData();
                    tableData.setMAXN("max" + i);
                    tableData.setMAX(split[0]);
                    for (int j = 1; j <= 10; j++) {
                        Field field1 = tableData.getClass().getDeclaredField("MAX" + j);
                        field1.setAccessible(true);
                        field1.set(tableData,split[j]);
                    }
                    tableDataList.add(tableData);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            vo.setList(tableDataList);
        }

        return vo;
    }

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void deleteData(IndustryDataVo industryDataVo) {
        Example example = new Example(IndustryData.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("datatime",industryDataVo.getDatatime());
        criteria.andEqualTo("plateno",industryDataVo.getPlateno());
        criteria.andEqualTo("lineno",industryDataVo.getLineno());

        industryDataMapper.deleteByExample(example);
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public List<IndustryData> queryDownloadData(IndustryDataVo industryDataVo) {
        Example example = new Example(IndustryData.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("lineno",industryDataVo.getLineno());
        criteria.andBetween("datatime",industryDataVo.getStartTime(),industryDataVo.getEndTime());

        List<IndustryData> industryData = industryDataMapper.selectByExample(example);
        return industryData;
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    @Override
    public EchartsVo getAllLBarChart(String userId) {
        EchartsVo echartsVo = new EchartsVo();

        List<String> factoryNames = new ArrayList<>();
        factoryNames.add("车间1");
        factoryNames.add("车间2");
        factoryNames.add("车间3");
        factoryNames.add("车间4");
        echartsVo.setFactoryNames(factoryNames);

        List<Integer> health = new ArrayList<>();
        health.add(1);
        health.add(4);
        health.add(6);
        health.add(2);
        echartsVo.setHealthValues(health);

        List<Integer> subHealth = new ArrayList<>();
        subHealth.add(2);
        subHealth.add(4);
        subHealth.add(8);
        subHealth.add(11);
        echartsVo.setSubHealthValues(subHealth);

        List<Integer> unHealth = new ArrayList<>();
        unHealth.add(3);
        unHealth.add(6);
        unHealth.add(9);
        unHealth.add(23);
        echartsVo.setUnHealthValues(unHealth);

        return echartsVo;
    }

    public DynamicChartVo getHealthCount(String equipNo,
                                         Double healthLimit, Double subHealthLimit, String startTime,String endTime){
        DynamicChartVo dynamicChartVo = industryDataMapper.getHealthCount(equipNo, healthLimit, subHealthLimit,startTime, endTime);
        return dynamicChartVo;
    }

    public PagedResult  getLifeCycleData(String subFactoryNo, Date startDate, Date endDate,int page,int pageSize ) {
        //根据车间号获取所有的设备号
        List<String> deviceNo = equipmentService.getEquipBySubFactoryId(subFactoryNo)
                .stream().map(Equipment::getEquipNo).collect(Collectors.toList());
        PageHelper.startPage(page,pageSize);
        List<IndustryDataVo> list = industryDataMapper.getLifeCycleData(deviceNo, startDate, endDate);
        PageInfo<IndustryDataVo> pageList = new PageInfo<>(list);
        PagedResult pagedResult = new PagedResult();
        pagedResult.setPage(page);
        pagedResult.setTotal(pageList.getPages());
        pagedResult.setRows(list);
        pagedResult.setRecords(pageList.getTotal());
        return pagedResult;
    }

    @Override
    public List<StrippingSpeedVo> getStrippingSpeedForClient(String subFactoryId) {

        // 获取该车间下的所有设备No
        List<String> deviceNo = equipmentService.getEquipBySubFactoryId(subFactoryId)
                .stream().map(Equipment::getEquipNo).collect(Collectors.toList());

        // 设置时间
        Calendar start = Calendar.getInstance();
        long currentTime = start.getTime().getTime();
        start.set(Calendar.HOUR_OF_DAY, 0);
        start.set(Calendar.MINUTE, 0);
        start.set(Calendar.SECOND, 0);
        start.set(Calendar.MILLISECOND, 0);
        Calendar end = Calendar.getInstance();
        end.set(Calendar.HOUR_OF_DAY, 0);
        end.set(Calendar.MINUTE, 59);
        end.set(Calendar.SECOND, 59);
        end.set(Calendar.MILLISECOND, 999);

        // 查询
        List result = new ArrayList<>();
        while (start.getTime().getTime() <= currentTime)
        {

            // 构建查询语句
            String linenoCondition = "LineNo in " +
                    deviceNo.stream().collect(Collectors.joining("','", "('", "')"));
            Example example = new Example(IndustryData.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andCondition(linenoCondition);
            criteria.andBetween("datatime", start.getTime(), end.getTime());

            // 返回结果
            result.add(new StrippingSpeedVo(start.get(Calendar.HOUR_OF_DAY)+":00", deviceNo.isEmpty() ? 0 : industryDataMapper.selectCountByExample(example)));

            // 时间后推
            start.add(Calendar.HOUR_OF_DAY, 1);
            end.add(Calendar.HOUR_OF_DAY, 1);

        }

        return result;
    }

    @Override
    public DynamicDetectVo getDynamicDetectPlate(String userId, Double needRepairThreshold, Integer page, Integer size) {

        String subFactoryId = userService.getUserById(userId).getSubFactoryId();

        // 获取该客户对应车间下的所有设备No
        List<String> deviceNo = equipmentService.getEquipBySubFactoryId(subFactoryId)
                .stream().map(Equipment::getEquipNo).collect(Collectors.toList());

        // 获取该客户对应车间
        Factory factory = factoryMapper.selectByPrimaryKey(subFactoryId);

        //设置当天时间
        Calendar todayStart = Calendar.getInstance();
        todayStart.set(Calendar.HOUR_OF_DAY, 0);
        todayStart.set(Calendar.MINUTE, 0);
        todayStart.set(Calendar.SECOND, 0);
        todayStart.set(Calendar.MILLISECOND, 0);
        Calendar todayEnd = Calendar.getInstance();
        todayEnd.set(Calendar.HOUR_OF_DAY, 23);
        todayEnd.set(Calendar.MINUTE, 59);
        todayEnd.set(Calendar.SECOND, 59);
        todayEnd.set(Calendar.MILLISECOND, 999);

        // 小于健康临界值就是健康、大于健康临界值小于亚健康临界值就是亚健康、大于亚健康临界值就是不健康
        Map<String, Long> dynamicDetectPlate = industryDataMapper.getDynamicDetectPlate(todayStart.getTime(), todayEnd.getTime(), deviceNo, factory.getEquipHealthLimit(), factory.getEquipSubHealthLimit(), needRepairThreshold);
        int detectNum = Math.toIntExact(dynamicDetectPlate.get("detectNum"));
        int healthNum = Math.toIntExact(dynamicDetectPlate.get("healthNum"));
        int subHealthNum = Math.toIntExact(dynamicDetectPlate.get("subHealthNum"));
        int needRepairPlatesCount = Math.toIntExact(dynamicDetectPlate.get("needRepairPlatesCount"));

        // // 健康查询
        // String linenoCondition = "LineNo in " + deviceNo.stream().collect(Collectors.joining("','", "('", "')"));
        // Example example = new Example(IndustryData.class);
        // Example.Criteria criteria = example.createCriteria();
        // criteria.andCondition(linenoCondition);
        // criteria.andBetween("datatime", todayStart.getTime(), todayEnd.getTime());
        // criteria.andBetween("max", -1*factory.getEquipHealthLimit(), factory.getEquipHealthLimit());
        // int healthNum = industryDataMapper.selectCountByExample(example);
        //
        // // 亚健康查询
        // example.clear();
        // criteria = example.createCriteria();
        // criteria.andCondition(linenoCondition);
        // criteria.andBetween("datatime", todayStart.getTime(), todayEnd.getTime());
        // criteria.andBetween("max", -1*factory.getEquipSubHealthLimit(), factory.getEquipSubHealthLimit());
        // int subHealthNum = industryDataMapper.selectCountByExample(example)-healthNum;
        //
        // // 检测总次数
        // example.clear();
        // criteria = example.createCriteria();
        // criteria.andCondition(linenoCondition);
        // criteria.andBetween("datatime", todayStart.getTime(), todayEnd.getTime());
        // int detectNum = industryDataMapper.selectCountByExample(example);
        //
        // // 建议维修阴极板总量
        // example.clear();
        // criteria = example.createCriteria();
        // criteria.andCondition(linenoCondition);
        // criteria.andBetween("datatime", todayStart.getTime(), todayEnd.getTime());
        // criteria.andCondition("abs(MAX) >= " + needRepairThreshold);
        // int needRepairPlatesCount = industryDataMapper.selectCountByExample(example);

        // 建议维修阴极板分页
        List<NeedRepairPlateVo> needRepairPlates = industryDataMapper.getNeedRepairPlates(deviceNo, todayStart.getTime(), todayEnd.getTime(), needRepairThreshold, (page-1)*size, size);
        // 分页后序号重排
        // needRepairPlates.forEach(i -> i.setSerialNum( i.getSerialNum() + (long) (page - 1) *size) );

        return new DynamicDetectVo(
                page, needRepairPlatesCount==0?1:(int) Math.ceil(1.0*needRepairPlatesCount/size), needRepairPlates.size(),
                factory.getEquipHealthLimit(), factory.getEquipSubHealthLimit(), detectNum, healthNum, subHealthNum, detectNum-healthNum-subHealthNum, needRepairPlates
        );
    }

    @Override
    public List getCopperProduction(String userId) {

        // 获取该管理员可以查看的所有车间
        List<Factory> factoryList = factoryService.getUserEquipFactory(userId);

        List<CopperProductionVo> result = factoryList.stream().map(i -> {
            // 获取所有车间对应的设备id
            List<String> equipNos = equipmentService.getEquipBySubFactoryId(i.getId()).stream().map(e -> e.getEquipNo()).collect(Collectors.toList());
            long sum = equipNos.stream().mapToLong(id -> {
                Long count = 0L;
                try {
                    // 获取某设备的铜离子产量
                    //count = copperParticleService.getAllRecordsFromCacheLength(id, IsOk.OK);
                    count = 0L;
                    List<CopperParticleCheckRecord> records = copperParticleService.getCopperParticleRecordsOfToday(id,IsOk.OK,null,null);
                    if (records != null){
                        count = (long) records.size();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return count;
            }).sum();
            return new CopperProductionVo(i.getFactoryName(), sum);
        }).collect(Collectors.toList());

        return result;

    }

    @Override
    public List getCopperDefect(String userId) {

        // 获取该管理员可以查看的所有车间
        List<Factory> factoryList = factoryService.getUserEquipFactory(userId);

        List<CopperDefectVo> result = factoryList.stream().map(i -> {

            // 获取所有车间对应的设备id
            List<String> equipNos = equipmentService.getEquipBySubFactoryId(i.getId()).stream().map(Equipment::getEquipNo).collect(Collectors.toList());

            // 获取某设备OK的铜离子产量
            long countOK = equipNos.stream().mapToLong(id -> {
                Long count = 0L;
                try {
                    // 获取某设备的铜离子产量
                    //count = copperParticleService.getAllRecordsFromCacheLength(id, IsOk.OK);
                    count = 0L;
                    List<CopperParticleCheckRecord> records = copperParticleService.getCopperParticleRecordsOfToday(id,IsOk.OK,null,null);
                    if (records != null){
                        count = (long) records.size();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return count;
            }).sum();

            // 获取某设备NG的铜离子产量
            long countNG = equipNos.stream().mapToLong(id -> {
                Long count = 0L;
                try {
                    // 获取某设备的铜离子产量
                    //count = copperParticleService.getAllRecordsFromCacheLength(id, IsOk.NG);
                    count = 0L;
                    List<CopperParticleCheckRecord> records = copperParticleService.getCopperParticleRecordsOfToday(id,IsOk.NG,null,null);
                    if (records != null){
                        count = (long) records.size();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return count;
            }).sum();

            return new CopperDefectVo(i.getFactoryName(), countOK, countNG);
        }).collect(Collectors.toList());

        return result;
    }

    @Override
    public List getStrippingSpeedForAdmin(String userId) {

        // 获取该管理员可以查看的所有车间
        List<Factory> factoryList = factoryService.getUserEquipFactory(userId);

        // 获取所有车间对应的机组拨片速度
        List<StrippingSpeedAllVo> result = factoryList.stream().map(i ->
                new StrippingSpeedAllVo(this.getStrippingSpeedForClient(i.getId()), i.getFactoryName()))
                .collect(Collectors.toList());

        return result;
    }
    @Override
    public  Integer getFailNumber(Date startTime,Date endTime,String equipNo){
        return industryDataMapper.getFailNumber(startTime,endTime,equipNo);
    }

    @Override
    public List<IndustryData> getIndustryDataListWithoutProductNo(Date startTime, Date endTime, String equipNo) {
        Example example = new Example(IndustryData.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andBetween("datatime",startTime,endTime);
        criteria.andEqualTo("plateno","0");
        example.setOrderByClause("datatime DESC");

        List<IndustryData> industryDataList = industryDataMapper.selectByExample(example);
        return industryDataList;
    }

    @Override
    public PagedResult getIndustryDataListWithoutProductNo(Date startTime, Date endTime, String equipNo, Integer page,
                                                           Integer pageSize) {
        Example example = new Example(IndustryData.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andBetween("datatime",startTime,endTime);
        //criteria.andEqualTo("plateno","0000000");
        criteria.andEqualTo("lineno",equipNo);

        criteria.andEqualTo("plateno","0");
        example.setOrderByClause("datatime DESC");

        PageHelper.startPage(page,pageSize);
        List<IndustryData> list = industryDataMapper.selectByExample(example);
        PageInfo<IndustryData> pageList = new PageInfo<>(list);
        PagedResult pagedResult = new PagedResult();
        pagedResult.setPage(page);
        pagedResult.setTotal(pageList.getPages());
        pagedResult.setRows(list);
        pagedResult.setRecords(pageList.getTotal());
        return pagedResult;
    }

    @Override
    public void updateProductNo(Date dataTime, String equipNo, String newProductNo) throws Exception {
        //合法性判断
        if (dataTime == null || StringUtils.isEmpty(equipNo) ||StringUtils.isEmpty(newProductNo)){
            throw new Exception("记录ID、设备编号或阴极板编号不能为空");
        }

        //更新阴极板编号
        industryDataMapper.updateProductNoOfRecord(dataTime,equipNo,newProductNo);
    }

    @Override
    public List<IndustryData> listIndustryData(String productCode, String equipNo, Date startTime, Date endTime) {
        Example example = new Example(IndustryData.class);
        Example.Criteria criteria = example.createCriteria();
        //阴极板编码条件
        if(!StringUtils.isEmpty(productCode)){
            criteria.andEqualTo("plateno",productCode);
        }
        //设备编号条件
        if(!StringUtils.isEmpty(equipNo)){
            criteria.andEqualTo("lineno",productCode);
        }
        //时间区间条件
        if(startTime!=null && endTime !=null) {
            criteria.andBetween("datatime", startTime, endTime);
        }
        example.setOrderByClause("datatime DESC");
        return industryDataMapper.selectByExample(example);
    }

    @Override
    public List<IndustryData> listIndustryData(String productCode) {
        if(StringUtils.isEmpty(productCode)){
            return null;
        }
        return listIndustryData(productCode,null,null,null);
    }
}
